package server;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import util.Hash;

import java.util.*;

/**
 * User: tum0r
 * Package Name: server
 * Time: 2019-03-10 Sunday 14:25:48
 */
public class UserServer extends BaseServer {
    public JSONObject searchUserByName(String username) {
        JSONObject result = new JSONObject();
        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select * from user where username=?", new Object[]{username});
        if (temp.size() != 0) {
            LinkedHashMap<String, Object> item = temp.get(0);
            Iterator<String> iterator = item.keySet().iterator();
            String key;
            while (iterator.hasNext()) {
                key = iterator.next();
                result.put(key, item.get(key) == null ? "" : item.get(key).toString());
            }
        }
        return result;
    }

    public JSONArray fuzzySearchUserByName(String username) {
        JSONArray result = new JSONArray();
        JSONObject resultItem;
        LinkedHashMap<String, Object> item;
        Iterator<String> iterator;
        String key;
        int size;

        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select * from user where username=? and type=?", new Object[]{username, 0});
        size = temp.size();
        for (int i = 0; i < size; i++) {
            item = temp.get(i);
            iterator = item.keySet().iterator();
            resultItem = new JSONObject();
            while (iterator.hasNext()) {
                key = iterator.next();
                resultItem.put(key, item.get(key) == null ? "" : item.get(key).toString());
            }
            result.add(resultItem);
        }

        temp = sql.query("select * from user where username like ? and type=? order by username", new Object[]{"%" + username + "%", 0});
        size = temp.size();
        for (int i = 0; i < size; i++) {
            item = temp.get(i);
            iterator = item.keySet().iterator();
            resultItem = new JSONObject();
            while (iterator.hasNext()) {
                key = iterator.next();
                resultItem.put(key, item.get(key) == null ? "" : item.get(key).toString());
            }
            if (!result.contains(resultItem)) {
                result.add(resultItem);
            }
        }

        StringBuilder fuzzy = new StringBuilder();
        char[] usernameCharArray = username.toCharArray();

        fuzzy.append("%");
        for (int i = 0; i < usernameCharArray.length; i++) {
            fuzzy.append(usernameCharArray[i]);
            fuzzy.append("%");
        }
        temp = sql.query("select * from user where username like ? and type=? order by username", new Object[]{fuzzy.toString(), 0});
        size = temp.size();
        for (int i = 0; i < size; i++) {
            item = temp.get(i);
            iterator = item.keySet().iterator();
            resultItem = new JSONObject();
            while (iterator.hasNext()) {
                key = iterator.next();
                resultItem.put(key, item.get(key) == null ? "" : item.get(key).toString());
            }
            if (!result.contains(resultItem)) {
                result.add(resultItem);
            }
        }
        return result;
    }

    public JSONObject searchUserByID(String userID) {
        JSONObject result = new JSONObject();
        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select * from user where uuid=?", new Object[]{userID});
        if (temp.size() != 0) {
            LinkedHashMap<String, Object> item = temp.get(0);
            Iterator<String> iterator = item.keySet().iterator();
            String key;
            while (iterator.hasNext()) {
                key = iterator.next();
                result.put(key, item.get(key) == null ? "" : item.get(key).toString());
            }
        }
        return result;
    }

    public int checkUserType(String username) {
        int result = -1;
        if (username != null) {
            LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select type from user where username=?", new Object[]{username});
            if (temp.size() != 0) {
                result = Integer.parseInt(temp.get(0).get("type").toString());
            }
        }
        return result;
    }

    public void setUserLastLanguage(String username, String language) {
        sql.update("update user set last_language=? where username=?", new Object[]{language, username});
    }

    public String getUserLastLanguage(String username) {
        String result = "";
        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select last_language from user where username=?", new Object[]{username});
        if (temp.size() != 0) {
            result = temp.get(0).get("last_language").toString();
        }
        return result;
    }

    public JSONArray getUserRecordResultAnalysis(String username) {
        JSONArray result = new JSONArray();
        JSONObject resultObject = new JSONObject();
        JSONObject languageObject = new JSONObject();
        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select uuid from user where username=?", new Object[]{username});
        if (temp.size() != 0) {
            String uuid = temp.get(0).get("uuid").toString();
            temp = sql.query("select result,language from record where user_id=?", new Object[]{uuid});
            Iterator<LinkedHashMap<String, Object>> iterator = temp.iterator();
            long count;
            String res;
            LinkedHashMap<String, Object> item;
            long sum = 0l;
            while (iterator.hasNext()) {
                sum++;
                item = iterator.next();
                res = item.get("result").toString();
                if (resultObject.has(res)) {
                    count = resultObject.getLong(res) + 1;
                    resultObject.replace(res, count);
                } else {
                    resultObject.put(res, 1l);
                }
                res = item.get("language").toString();
                if (languageObject.has(res)) {
                    count = languageObject.getLong(res) + 1;
                    languageObject.replace(res, count);
                } else {
                    languageObject.put(res, 1l);
                }
            }
            resultObject.put("sum", sum);
        }
        result.add(resultObject);
//        result.add(languageObject);
        return result;
    }

    public JSONArray getAllUserRecordResultAnalysis() {
        JSONArray result = new JSONArray();
        JSONObject resultObject = new JSONObject();
        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select result from record", null);
        Iterator<LinkedHashMap<String, Object>> iterator = temp.iterator();
        long count;
        String res;
        LinkedHashMap<String, Object> item;
        long sum = 0l;
        while (iterator.hasNext()) {
            sum++;
            item = iterator.next();
            res = item.get("result").toString();
            if (resultObject.has(res)) {
                count = resultObject.getLong(res) + 1;
                resultObject.replace(res, count);
            } else {
                resultObject.put(res, 1l);
            }
        }
        resultObject.put("sum", sum);
        result.add(resultObject);
        return result;
    }

    public LinkedList<LinkedHashMap<String, Object>> getUserRecordResult(String username) {
        LinkedList<LinkedHashMap<String, Object>> result = new LinkedList<>();
        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select uuid from user where username=?", new Object[]{username});
        if (temp.size() != 0) {
            String uuid = temp.get(0).get("uuid").toString();
            result = sql.query("select * from record where user_id=? order by submit_time desc", new Object[]{uuid});
        }
        return result;
    }

    public LinkedList<LinkedHashMap<String, Object>> getAllUserRecordResult() {
        return sql.query("select * from record order by submit_time desc", null);
    }

    public JSONArray getUserInformation() {
        JSONArray result = new JSONArray();
        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select * from user order by type desc;", null);
        LinkedHashMap<String, Object> item;
        Iterator<LinkedHashMap<String, Object>> iterator = temp.iterator();
        JSONObject items;
        Iterator<String> keys;
        String key;
        while (iterator.hasNext()) {
            item = iterator.next();
            items = new JSONObject();
            keys = item.keySet().iterator();
            while (keys.hasNext()) {
                key = keys.next();
                items.put(key, item.get(key) != null ? item.get(key) : "");
            }
            result.add(items);
        }
        return result;
    }

    public int getPlayerCount() {
        return sql.query("select * from user where type=?", new Object[]{0}).size();
    }

    public void changeUserInformation(String oldUsername, String user, String realName, String sex, String clothes_size, String phone, String email) {
        SettingServer settingServer = new SettingServer();
        settingServer.open();
        boolean mutable = settingServer.readSettingObject("team").getBoolean("mutable");
        settingServer.close();
        if (mutable) {
            sql.update("update user set username=?,real_name=?,sex=?,clothes_size=?,phone=?,email=? where username=?", new Object[]{user, realName, sex, clothes_size, phone, email, oldUsername});
        } else {
            sql.update("update user set real_name=?,sex=?,clothes_size=?,phone=?,email=? where username=?", new Object[]{realName, sex, clothes_size, phone, email, oldUsername});
        }
        sql.update("update login set user_name=?,time=? where user_name=?", new Object[]{user, new Date().getTime(), oldUsername});
    }

    public void changeIcon(String user, String fileID) {
        sql.update("update user set icon=? where username=?", new Object[]{"{\"uuid\":\"" + fileID + "\", \"name\":\"" + user + " 的头像\"}", user});
    }

    public void changeUserPassword(String user, String password) {
        Hash hash = new Hash();
        sql.update("update user set password=? where username=?", new Object[]{hash.passwordEncryption(password), user});
    }

    public int changeUserPassword(String user, String oldPassword, String password) {
        Hash hash = new Hash();
        return sql.update("update user set password=? where username=? and password=?", new Object[]{hash.passwordEncryption(password), user, hash.passwordEncryption(oldPassword)});
    }

    public int canChange(String user, String changeUser) {
        int result = 0;
        if (user.equals(changeUser)) {
            result = 1;
        } else {
            LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select type from user where username=?", new Object[]{user});
            if (temp.size() > 0 && Integer.parseInt(temp.get(0).get("type").toString()) == 1) {
                result = 2;
            }
        }
        return result;
    }

    public boolean getUserState(String user) {
        boolean result = false;
        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select state from user where username=?", new Object[]{user});
        if (temp.size() > 0 && Integer.parseInt(temp.get(0).get("state").toString()) == 1) {
            result = true;
        }
        return result;
    }

    public void changeUserState(String user) {
        if (getUserState(user)) {
            sql.update("update user set state=0 where username=?", new Object[]{user});
        } else {
            sql.update("update user set state=1 where username=?", new Object[]{user});
        }
    }

    public void deleteUser(String user) {
        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select uuid from user where username=?", new Object[]{user});
        if (temp.size() > 0) {
            sql.update("delete from user where username=?", new Object[]{user});
            sql.update("delete from record where user_id=?", new Object[]{temp.get(0).get("uuid").toString()});
        }
    }

    public void clearUser(String user, String mode) {
        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select uuid from user where username=?", new Object[]{user});
        if (temp.size() > 0) {
            String uuid = temp.get(0).get("uuid").toString();
            switch (mode) {
                case "1":
                    temp = sql.query("select uuid from user where uuid!=? and type=?", new Object[]{uuid, 1});
                    break;
                case "2":
                    temp = sql.query("select uuid from user where uuid!=?", new Object[]{uuid});
                    break;
                default:
                    temp = sql.query("select uuid from user where uuid!=? and type=?", new Object[]{uuid, 0});
                    break;
            }
            for (int i = 0; i < temp.size(); i++) {
                uuid = temp.get(i).get("uuid").toString();
                sql.update("delete from user where uuid=?", new Object[]{uuid});
                sql.update("delete from record where user_id=?", new Object[]{uuid});
            }
        }
    }

    public void changeUserGroup(String user) {
        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select type from user where username=?", new Object[]{user});
        if (temp.size() > 0) {
            int type = temp.get(0).get("type") == null ? 0 : Integer.parseInt(temp.get(0).get("type").toString());
            type = type == 0 ? 1 : 0;
            sql.update("update user set type=? where username=?", new Object[]{type, user});
        }
    }

    public JSONArray getUsersClotheSize() {
        JSONArray result = new JSONArray();
        JSONObject player = new JSONObject();
        JSONObject manager = new JSONObject();
        LinkedList<LinkedHashMap<String, Object>> temp = sql.query("select clothes_size,type from user order by clothes_size", null);
        String clothesSize;
        for (int i = 0; i < temp.size(); i++) {
            clothesSize = temp.get(i).get("clothes_size") == null ? "未知" : temp.get(i).get("clothes_size").toString().trim().equals("") ? "未知" : temp.get(i).get("clothes_size").toString().toUpperCase();
            if (Integer.parseInt(temp.get(i).get("type").toString()) == 0) {
                if (player.has(clothesSize)) {
                    player.replace(clothesSize, player.getInt(clothesSize) + 1);
                } else {
                    player.put(clothesSize, 1);
                }
            } else {
                if (manager.has(clothesSize)) {
                    manager.replace(clothesSize, manager.getInt(clothesSize) + 1);
                } else {
                    manager.put(clothesSize, 1);
                }
            }
        }
        result.add(player);
        result.add(manager);
        return result;
    }

    public void randomUser(int count, String prefix, String suffix, int length) {
        count = count <= 0 ? 1 : count;
        prefix = prefix == null ? "" : prefix;
        suffix = suffix == null ? "" : suffix;
        Hash hash = new Hash();
        StringBuilder name = new StringBuilder();
        Random random = new Random();
        char temp;
        for (int i = 0; i < count; i++) {
            while (name.toString().equals("") || searchUserByName(name.toString()).size() != 0) {
                name.delete(0, name.length());
                for (int j = 0; j < length; j++) {
                    temp = (char) ('A' + random.nextInt(26));
                    while (temp == 'O' || temp == 'I' || temp == 'L') {
                        temp = (char) ('A' + random.nextInt(26));
                    }
                    name.append(temp);
                }
            }
            name.insert(0, prefix);
            name.append(suffix);
            sql.update("insert into user(uuid, username, password, icon, type, last_language, state) value(?, ?, ?, ?, ?, ?, ?)", new Object[]{UUID.randomUUID().toString(), name.toString(), hash.passwordEncryption(name.toString()), "{}", 0, "Java", 1});
        }
    }

}
